package com.loc.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

import com.loc.dao.MenusDao;
import com.loc.dao.RolesDao;
import com.loc.pojo.Menu;
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource{
	private static RolesDao rolesDao;
	private static MenusDao menusDao;
	private static Map<String,Collection<ConfigAttribute>> resourceMap = null;
	private UrlMatcher urlMatcher = new AntUrlPathMatcher();   
	public MySecurityMetadataSource(RolesDao rolesDao,MenusDao menusDao) throws Exception{
		MySecurityMetadataSource.rolesDao = rolesDao;
		MySecurityMetadataSource.menusDao = menusDao;
		loadResourceDefine();
	}
	private static void loadResourceDefine() throws Exception{
		if(resourceMap == null){
			resourceMap = new HashMap<String,Collection<ConfigAttribute>>();
			Map<Object, List<String>> map = rolesDao.findAll();
			List<Menu> menus = menusDao.findAll();
			if(menus!=null){
				for(Menu menu:menus){
					Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
					List<String> tmp = map.get(menu.getMenu_url());
					if(tmp!=null){
						for(String temp:tmp){
							ConfigAttribute configAttribute = new SecurityConfig(temp);
							configAttributes.add(configAttribute);
						}
						resourceMap.put(menu.getMenu_url(), configAttributes);
					}
				}
			}
		}
	}
	public static Map<String, Collection<ConfigAttribute>> getResourceMap() {
		return resourceMap;
	}
	public static void setResourceMap(Map<String, Collection<ConfigAttribute>> resourceMap) {
		MySecurityMetadataSource.resourceMap = resourceMap;
	}
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
        for (Map.Entry<String,  Collection<ConfigAttribute>> entry : resourceMap.entrySet()) {
            for (ConfigAttribute attrs : entry.getValue()) {
                allAttributes.add(attrs);
            }
        }
        return allAttributes;
	}

	public Collection<ConfigAttribute> getAttributes(Object arg0)
			throws IllegalArgumentException {
		String url = ((FilterInvocation)arg0).getRequestUrl();
		if(url.equals("/j_spring_security_check")){
			return null;
		}
		Iterator<String> ite = resourceMap.keySet().iterator();
		String tempUrl="/**";
		int tempIndex=0;
		while(ite.hasNext()){
			String resURL = ite.next();
			if(urlMatcher.pathMatchesUrl(resURL,url)){
				int s=resURL.indexOf("/**");
				if(s>-1){
					if(s>tempIndex){
						tempUrl=resURL;
						tempIndex=s;
					}
					continue;
				}
				Collection<ConfigAttribute> returnCollection = resourceMap.get(resURL);
				return returnCollection;
			}
		}
		return resourceMap.get(tempUrl);
	}

	public boolean supports(Class<?> arg0) {
		return true;
	}
	public static void reload()throws Exception{
		resourceMap=null;
		loadResourceDefine();
	}
}
